/***
 * @Author: LVGRAPE
 * @Date: 2024-01-09 17:53:09
 * @LastEditTime: 2024-02-21 09:35:08
 * @LastEditors: LVGRAPE
 * @Description:
 * @FilePath: \ble_aromatherapy_diffuser\AromatherapyDiffuser\hardware\W25QXX\w25qxx.h
 * @要啥没啥，爱咋咋的
 */

#ifndef __W25QXX_H_
#define __W25QXX_H_
#ifdef __cplusplus
extern "C"
{
#endif // __cplusplus

#include <stdint.h>
/**
 * @defgroup W25QXX_Global_Macros W25QXX Global Macros
 * @{
 */

/**
 * @defgroup W25QXX_ID W25QXX ID
 * @{
 */
#define W25Q80                  (0xEF13U)
#define W25Q16                  (0xEF14U)
#define W25Q32                  (0xEF15U)
#define W25Q64                  (0xEF16U)
#define W25Q128                 (0xEF17U)
/**
 * @}
 */

/**
 * @defgroup W25QXX_Command W25QXX Command
 * @{
 */
#define W25QXX_WRITE_ENABLE                     (0x06U)
#define W25QXX_VOLATILE_SR_WRITE_ENABLE         (0x50U)
#define W25QXX_WRITE_DISABLE                    (0x04U)
#define W25QXX_RELEASE_POWER_DOWN_ID            (0xABU)
#define W25QXX_MANUFACTURER_DEVICE_ID           (0x90U)
#define W25QXX_JEDEC_ID                         (0x9FU)
#define W25QXX_READ_UNIQUE_ID                   (0x4BU)
#define W25QXX_READ_DATA                        (0x03U)
#define W25QXX_FAST_READ                        (0x0BU)
#define W25QXX_PAGE_PROGRAM                     (0x02U)
#define W25QXX_SECTOR_ERASE                     (0x20U)
#define W25QXX_BLOCK_ERASE_32KB                 (0x52U)
#define W25QXX_BLOCK_ERASE_64KB                 (0xD8U)
#define W25QXX_CHIP_ERASE                       (0xC7U)
#define W25QXX_READ_STATUS_REGISTER_1           (0x05U)
#define W25QXX_WRITE_STATUS_REGISTER_1          (0x01U)
#define W25QXX_READ_STATUS_REGISTER_2           (0x35U)
#define W25QXX_WRITE_STATUS_REGISTER_2          (0x31U)
#define W25QXX_READ_STATUS_REGISTER_3           (0x15U)
#define W25QXX_WRITE_STATUS_REGISTER_3          (0x11U)
#define W25QXX_READ_SFDP_REGISTER               (0x5AU)
#define W25QXX_ERASE_SECURITY_REGISTER          (0x44U)
#define W25QXX_PROGRAM_SECURITY_REGISTER        (0x42U)
#define W25QXX_READ_SECURITY_REGISTER           (0x48U)
#define W25QXX_GLOBAL_BLOCK_LOCK                (0x7EU)
#define W25QXX_GLOBAL_BLOCK_UNLOCK              (0x98U)
#define W25QXX_READ_BLOCK_LOCK                  (0x3DU)
#define W25QXX_INDIVIDUAL_BLOCK_LOCK            (0x36U)
#define W25QXX_INDIVIDUAL_BLOCK_UNLOCK          (0x39U)
#define W25QXX_ERASE_PROGRAM_SUSPEND            (0x75U)
#define W25QXX_ERASE_PROGRAM_RESUME             (0x7AU)
#define W25QXX_POWER_DOWN                       (0xB9U)
#define W25QXX_ENABLE_RESET                     (0x66U)
#define W25QXX_RESET_DEVICE                     (0x99U)

#define W25QXX_FLAG_BUSY            (1UL << 0U)
#define W25QXX_FLAG_WEL             (1UL << 1U)         /*!< Write Enable Latch */
#define W25QXX_FLAG_SUSPEND         (1UL << 15U)        /*!< Write Enable Latch */

int w25qxx_init();
void w25qxx_WriteCmd(uint8_t cmd, uint8_t *cmdData, uint32_t cmdDataLen);
void w25qxx_ReadCmd(uint8_t cmd, uint8_t *cmdData, uint32_t cmdDataLen, uint8_t *data, uint32_t dataLen);
void w25qxx_WriteEnable(void);
void w25qxx_WriteDisable(void);
uint16_t w25qxx_GetManDeviceId(void);
void w25qxx_ReadUniqueID(uint8_t *id);
uint8_t w25qxx_ReadStatus(uint8_t RdCmd);
void w25qxx_WriteStatus(uint8_t WtCmd, uint8_t status);
void w25qxx_PowerDown(void);
void w25qxx_ReleasePowerDown(void);
void w25qxx_EraseChip(void);
void w25qxx_EraseSector(uint32_t SectorAddr);
void w25qxx_ReadData(uint32_t ReadAddr, uint8_t *ReadBuf, uint32_t ReadSize);
void w25qxx_FastRead(uint32_t ReadAddr, uint8_t* ReadBuf, uint16_t ReadSize);
void w25qxx_PageProgram(uint32_t WriteAddr, uint8_t *WriteBuf, uint32_t WriteSize);
int w25qxx_WaitProcessDone(void);
void w25qxx_WaitBusy();
void w25qxx_SectorProgram_4K(uint32_t WriteAddr, uint8_t* WriteBuf, uint32_t WriteSize);
// void flash_read(uint32_t offset, uint32_t length, uint8_t *buffer);

void get_data_task(int len, uint8_t *data);


#define MSG_DATA_SIZE_MAX 256
#define MSG_PACK_SIZE (MSG_DATA_SIZE_MAX + 9)

#ifndef __packed
#define __packed __attribute__((packed))
#endif

struct msg_pack
{
    uint8_t cmd[2];
    uint8_t addr[4];
    uint16_t data_size;
    uint8_t data_check;
    uint8_t data[MSG_DATA_SIZE_MAX];
} __packed;
struct sbc_info
{
    uint8_t head;
    uint32_t addr;
    uint32_t size;
    uint8_t name_len;
    uint8_t name[245];
    uint8_t tail;
} __packed;

#ifdef __cplusplus
}
#endif // __cplusplus
#endif
